package main.view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import main.model.DataModel;
import main.model.Day;


/**
 * @author Yaqi Zhang
 *
 *
 */


public class LineGraph extends Visualizer {
    /**
     * Diameter of an oval.
     */

    public static final int DIAMETER = 5;
    private static final int NUMBEROFMARKS = 10;
    private static final int DATESTRINGLENGTH = 90;
    private final Dimension mySize;
    private final HashMap<Integer, List<Object>> myMap;

    /**
     * Constructor for LineGraph Visualizer.
     *
     * @param dataModel model to initialize with
     * @param size size of visualization
     */
    public LineGraph (DataModel dataModel, Dimension size) {
        super(dataModel, size);
        mySize = size;
        setMyXAxis("Date");
        setMyYAxis("Price(Dollar)");
        myMap = new HashMap<Integer, List<Object>>();
    }

    @SuppressWarnings("unchecked")
    @Override
    public void paint (Graphics pen) {
        super.paint(pen);
        DataModel data = super.getData();
        if (data == null) { return; }
        if (data.isEmpty()) { return; }
        float xScale = ((float) (mySize.width - super.getLeftMargin())) /
                data.getSizeOfData();
        float yScale = (mySize.height - super.getBottomMargin()) /
                (data.getMaxRow().getHigh() - data.getMinRow().getLow());
        int previousXVal = getLeftMargin();
        // Initialize initial x value for starting points and a counter
        float xValF = super.getLeftMargin();
        for (Day d : data) {
            xValF += xScale;
            int yHigh = Math.round(mySize.height - super.getBottomMargin() -
                    (d.getHigh() - data.getMinRow().getLow()) * yScale);
            int yLow = Math.round(mySize.height - super.getBottomMargin() -
                    (d.getLow() - data.getMinRow().getLow()) * yScale);
            pen.setColor(Color.BLUE);
            int xVal = Math.round(xValF);
            pen.drawLine(xVal+DIAMETER/2, yHigh+DIAMETER/2, xVal+DIAMETER/2, yLow);
            // black for open
            pen.setColor(Color.GREEN);
            pen.fillOval(xVal, yHigh, DIAMETER, DIAMETER);
            // blue for close
            pen.setColor(Color.RED);
            pen.fillOval(xVal, yLow, DIAMETER, DIAMETER);
            @SuppressWarnings("rawtypes")
            List list = new ArrayList();
            list.add(yHigh);
            list.add(yLow);
            list.add(d);
            myMap.put(xVal, list);
            if (xVal > previousXVal + DATESTRINGLENGTH && previousXVal +
                    DATESTRINGLENGTH < getMyWidth()) {
                previousXVal = labelXAxis(pen, xVal, d);
            }
        }
        labelYAxis(NUMBEROFMARKS, data.getMaxRow().getHigh(), data.getMinRow().getLow(), pen);
    }

    /**
     * @author Seon Kang
     * @param pen
     * @param xVal
     * @param d
     * @return
     */
    private int labelXAxis (Graphics pen, int xVal, Day d) {
        int previousXVal;
        pen.setColor(Color.GRAY);
        SimpleDateFormat formatter = new SimpleDateFormat("MM/dd");
        String date = formatter.format(d.getDate());
        pen.drawString(date,
                xVal, getMyHeight() - getBottomMargin() / 2);
        previousXVal = xVal;
        return previousXVal;
    }

    /**
     * @return the map between high and low point location drew on canvas
     *         and the Day object.
     */
    @Override
    public HashMap<Integer, List<Object>> getPointMap () {
        return myMap;
    }
}
